home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
9-Digit Zip Code Directory
/
9-Digit Zip Code Directory (American Business Information) (ABIZIP-12).ISO
/
z4src.zip
/
BSSLEEP.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-05-30
|
7KB
|
212 lines
//----------------------------------------------------------------------------
// MODULE DESCRIPTION
//
// Module: bssleep.c
// Title: Base library
// Notice: John M. Weeder
// Copyright (c) 1993. All rights reserved.
// This module contains proprietary information and should be
// treated as confidential.
//
//----------------------------------------------------------------------------
// MAINTENANCE HISTORY
//
// $Workfile$
// $Revision$
// $Author$
// $Date$
// $Log$
//
//----------------------------------------------------------------------------
// MODULE NARRATIVE
//
//
// This module contains to delay program execution.
// Under OS/2, a delay of 0 causes the current thread to give up its time
// slice.
//
// This code is not implemented under SCO UNIX or Windows.
// Also, the MSC compiler does not provide a startup pragma so initialization
// is not performed correctly with that compiler.
//
// The code in this module should be written entirely in C.
// Do not use any C++ constructs.
//
// This module is portable to:
// DOS 3.X+
// OS/2 2.X+
//
// The following compilers are supported:
// Borland C++ 3.1 for DOS
// Borland C++ 1.0 for OS/2 2.X
//
//----------------------------------------------------------------------------
#include <bs.h>
//----------------------------------------------------------------------------
// Prototypes
//----------------------------------------------------------------------------
#if OS_DOS
static void near dummy(void);
static USHORT FN_A ReadTimer(void);
#endif
//----------------------------------------------------------------------------
// Local Data
//----------------------------------------------------------------------------
#if OS_DOS
static ULONG ulMultiplier = 1193*2L;
#endif
//----------------------------------------------------------------------------
// Description: Dummy function. Does nothing but waste time
// Parameters:
// Globals:
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
#if OS_DOS
static void near dummy(void)
{
return ;
}
#endif
//----------------------------------------------------------------------------
// Description: Obtain the complement of the value in timer 0. The
// complement is used so that the timer will appear to
// count up rather than down. The value returned will
// range from 0 to 0xffff.
// Parameters:
// Globals:
// Returns: The complement of the value in timer 0.
//----------------------------------------------------------------------------
#if OS_DOS
static USHORT FN_A ReadTimer(void)
{
asm {
pushf // Save interrupt flag
cli // Disable interrupts
mov al,0h // Latch timer 0
out 43h,al
}
dummy(); // Waste some time
asm {
in al,40h // Counter --> bx
mov bl,al // LSB in BL
}
dummy(); // Waste some time
asm {
in al,40h
mov bh,al // MSB in BH
not bx // Need ascending counter
popf // Restore interrupt flag
}
return _BX;
}
#endif
//----------------------------------------------------------------------------
// Description: The current thread of execution is suspended for the
// specified number of milliseconds.
// Parameters: ulMSecs Number of milleseconds to sleep.
// If 0, the current time-slice is given up.
// Default is 0.
// Globals:
// Returns: void
//----------------------------------------------------------------------------
VOID FN_E Sleep(ULONG ulMSecs)
{
#if OS_OS2 || OS_PM
// If sleep == 0L, OS/2 gives up current time slice
DosSleep(ulMSecs);
#elif OS_WINDOWS
// This should find a way to give up the time slice or whatever.
NOTUSED(ulMSecs);
#elif OS_DOS
ULONG stop;
USHORT cur, prev;
if (!ulMSecs) // Early out!
{
_asm {
mov ax, 1680h // Give Window's the time slice
int 2fh
}
return ;
}
stop = (prev = ReadTimer()) + (ulMSecs * ulMultiplier);
while ((cur = ReadTimer()) < stop)
{
if (cur < prev) // Check for timer wraparound
{
if (stop < 0x10000L)
break;
stop -= 0x10000L;
}
prev = cur;
}
#else // Unix! (second resolution only)
sleep((ulMSecs+999L)/1000L);
#endif
return ;
}
//----------------------------------------------------------------------------
// Description: Determine the multiplier required to convert milliseconds
// to an equivalent interval timer value. Interval timer 0
// is normally programmed in mode 3 (square wave), where
// the timer is decremented by two every 840 nanoseconds;
// in this case the multiplier is 2386. However, some
// programs and device drivers reprogram the timer in mode 2,
// where the timer is decremented by one every 840 ns; in this
// case the multiplier is halved, i.e. 1193.
//
// When the timer is in mode 3, it will never have an odd value.
// In mode 2, the timer can have both odd and even values.
// Therefore, if we read the timer 100 times and never
// see an odd value, it's a pretty safe assumption that
// it's in mode 3. This is the method used in timer_init.
// Parameters:
// Globals:
// Returns: void
//----------------------------------------------------------------------------
#if OS_DOS
VOID FN SleepInitialize(void)
{
SHORT i;
for (i = 0; i < 100; i++)
if ((ReadTimer() & 1) == 0) // ReadTimer() returns complement
{
ulMultiplier = 1193L;
return;
}
return ;
}
#endif
//----------------------------------------------------------------------------
// Description: Run standard test suite
// Parameters: sTest Number of milliseconds to sleep.
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
#if COMPILE_TEST
BOOL FN SleepTest(SHORT sTest)
{
Sleep((ULONG)sTest);
return TRUE;
}
#endif
//----------------------------------------------------------------------------
//------------------------------- End of File --------------------------------
//----------------------------------------------------------------------------